package com.frank.loadinglibrary.special.cool.ball;

import com.frank.loadinglibrary.utils.SimpleAnimatorListener;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;

public class SecCoolBall extends CoolBall {
    private final float valueZeroPointFive = 0.5f;
    private final float valueOnePointFive = 1.5f;
    private final float valueTwo = 2.0f;
    private final float valueTwoPointTwoFive = 2.25f;
    private final float valueThree = 3.0f;
    private final float valueFour = 4.0f;
    private final float valueFive = 5.0f;
    private final int valueTwenty = 20;
    //移动长度
    private final int MOVE_MAX_LINTH = 120;
    //环绕线粗，应为AROUND_POINT_RADIUS*2;
    private final int LINE_STROKE_LENGTH = 8;
    //环绕行星(圆)半径
    private final int AROUND_POINT_RADIUS = 4;

    //红球外半径,比最大半径稍微一点
    private int mRedCirCleRadius = 50;
    //红球内半径
    private int mRedCirStrokeFactor;
    //环绕线内点
    private int mAroundLineInsideP = MAX_RADIUS_CIRCLE;
    //环绕线外点
    private int mAroundLineOutsideP = MAX_RADIUS_CIRCLE;
    //环绕角度
    private int mAroundLineDegrees = 0;
    //环绕偏离中心的坐标
    private int mAroundPointY = 0;


    //这个方式待修改完善。
    private int mFirYellowCirRadius;
    //黄球左偏移
    private int mLineLeftOffset;
    //黄球右偏移
    private int mLineRightOffset;
    private int mLineStrokeWidth = 120;

    private boolean mIsCirLineShow = true;
    //环绕行星可见性
    private boolean mIsAroundPointV = false;

    //第二个黄色球
    private int mSecYellowCirRadius;

    private Paint mPaint;
    // 正在结束,只绘制结束动画
    private boolean isMoveEnd = false;

    private AnimatorValue mEndAnimator;
    private int mEndCirIRadius;
    private int mEndCirMRadius;
    private int mEndCirORadius;

    private AnimatorValue firAnimator;
    private AnimatorValue secAnimator;
    private AnimatorValue thirdAnimator;
    private final int value_2 = 2;
    private final int value_8 = 8;
    private final float value_1 = 1.0f;

    public SecCoolBall(float x, float y) {
        super(x, y);
    }

    @Override
    protected void initConfig() {
        super.initConfig();
        initPaint();
    }

    @Override
    public void reset() {
        super.reset();
        isMoveEnd = false;
        mIsCirLineShow = true;
        //环绕行星可见性
        mIsAroundPointV = false;
        mAroundLineInsideP = MAX_RADIUS_CIRCLE;
        mAroundLineOutsideP = MAX_RADIUS_CIRCLE;
    }

    @Override
    public void drawSelf(Canvas canvas) {
        super.drawSelf(canvas);

        if (!isMoveEnd) {
            if (mPaint.getStyle() != Paint.Style.STROKE_STYLE) {
                mPaint.setStyle(Paint.Style.STROKE_STYLE);
            }
            mPaint.setColor(Color.YELLOW);
            mPaint.setStrokeWidth(mSecYellowCirRadius);
            canvas.drawCircle(getCurX(), getCurY(), mSecYellowCirRadius / 2, mPaint);

            mPaint.setColor(Color.RED);
            mPaint.setStrokeWidth(mRedCirStrokeFactor);
            canvas.drawCircle(getCurX(), getCurY(), mRedCirCleRadius - mRedCirStrokeFactor / 2, mPaint);

            mPaint.setColor(Color.YELLOW);
            mPaint.setStrokeWidth(mFirYellowCirRadius);
            canvas.drawCircle(getCurX(), getCurY(), mFirYellowCirRadius / 2, mPaint);


            //黄色圆移动，等同圆角的线
            //TODO 结尾问题。
            if (mIsCirLineShow) {
                mPaint.setStrokeWidth(mLineStrokeWidth);
                canvas.drawLine(getCurX() + mLineRightOffset, getCurY(), getCurX() + mLineLeftOffset, getCurY(), mPaint);
            }

            drawAroundLine(canvas);
            if (mIsAroundPointV) {
                drawAroundPoint(canvas);
            }
        }

        if (mIsEnd) {
            if (!mIsEndAnimStart) {
                mEndAnimator.start();
                mIsEndAnimStart = true;
            }
            mPaint.setStyle(Paint.Style.FILL_STYLE);
            mPaint.setColor(Color.GREEN);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirIRadius, mPaint);
            mPaint.setColor(Color.YELLOW);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirMRadius, mPaint);
            mPaint.setColor(Color.RED);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirORadius, mPaint);
            mPaint.setStyle(Paint.Style.STROKE_STYLE);


        }

    }

    private void drawAroundLine(Canvas canvas) {
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(LINE_STROKE_LENGTH);
        if (Math.abs(mAroundLineOutsideP - mAroundLineInsideP) >= value_2) {
            for (int i = 0; i < value_8; i++) {
                canvas.save();
                canvas.rotate(45 * i + mAroundLineDegrees, getCurX(), getCurY());
                canvas.drawLine(getCurX(), getCurY() - mAroundLineOutsideP, getCurX(), getCurY() - mAroundLineInsideP, mPaint);
                canvas.restore();
            }
        }
    }

    private void drawAroundPoint(Canvas canvas) {
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        for (int i = 0; i < value_8; i++) {
            mPaint.setAlpha(160);
            canvas.save();
            canvas.rotate(45 * i + mAroundLineDegrees, getCurX(), getCurY());
            canvas.drawCircle(getCurX(), getCurY() - MAX_RADIUS_CIRCLE / 2 - mAroundPointY, AROUND_POINT_RADIUS, mPaint);
            canvas.restore();
        }
    }

    @Override
    protected void initAnim() {
        initFirstAnimation();

        initSecAnimation();

        initThirdAnimation();
    }

    private void initThirdAnimation() {
        //黄球（环）放大，再缩小，缩小过程伴随着环绕行星点变线向内伸长。
        thirdAnimator = new AnimatorValue();
        thirdAnimator.setDuration(3000);
        thirdAnimator.setLoopedCount(0);
        thirdAnimator.setValueUpdateListener((animatorValue, v) -> {
            float factor = (float) 5 * v;
            float changeValue = 0;
            if (factor < value_1) {
                //黄球放大
                mSecYellowCirRadius = (int) (30 + 15 * (factor));
            } else if (factor < valueTwo) {
                changeValue = 2 - factor;
                //黄球缩小
                mSecYellowCirRadius = (int) (45 * changeValue);
                //点成线
                mAroundLineInsideP = MAX_RADIUS_CIRCLE - (int) (MAX_RADIUS_CIRCLE / 3 * (1 - changeValue));
            } else if (factor < valueTwoPointTwoFive) {
                //停顿一下。
            } else if (factor < valueThree) {
                changeValue = (3.0f - factor) * 4 / 3;
                //线内聚
                mIsAroundPointV = false;
                mAroundLineOutsideP = (int) (MAX_RADIUS_CIRCLE * changeValue);
                mAroundLineInsideP = (int) (MAX_RADIUS_CIRCLE / 3 * 2 * changeValue);
                //黄球缩小,红球放大
                mFirYellowCirRadius = (int) (10 * changeValue);
                mRedCirStrokeFactor = 30;
                mRedCirCleRadius = (int) (20 + 15 * (1 - changeValue));
            } else if (factor < valueFour) {
                //停顿一下
            } else if (factor < valueFive) {
                changeValue = factor - 4.0f;
                //红球（环）内边外扩，内部黄球放大
                mFirYellowCirRadius = (int) (20 * changeValue);
                mRedCirStrokeFactor = (int) (30 - 16 * changeValue);
                mRedCirCleRadius = (int) (35 + 8 * changeValue);
            }
        });
        thirdAnimator.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                mAroundLineInsideP = MAX_RADIUS_CIRCLE;
                mAroundLineOutsideP = MAX_RADIUS_CIRCLE;
                mLineLeftOffset = 0;
                mLineRightOffset = 0;
                if (mAnimatorStateListen != null) {
                    mAnimatorStateListen.onAnimatorEnd();
                }
            }
        });
    }

    private void initSecAnimation() {
        secAnimator = new AnimatorValue();
        secAnimator.setDuration(2400);
        secAnimator.setLoopedCount(0);
        secAnimator.setValueUpdateListener((animatorValue, v) -> {
            float factor = (float) 2 * v;
            float changeValue = 0;
            if (factor <= value_1) {
                mLineRightOffset = (int) (MOVE_MAX_LINTH * factor);
            } else {
                changeValue = 2 - factor;
                //线变短变成圆一会消失，交给第三个小球处理
                mIsCirLineShow = false;
                mAroundLineDegrees = (int) (90 * changeValue);
                if (factor < valueOnePointFive) {
                    changeValue = (1.5f - factor) * 2;
                    mAroundLineInsideP = MAX_RADIUS_CIRCLE - (int) (MAX_RADIUS_CIRCLE * changeValue);
                    //红球缩小至20时就停止缩小
                    if (mRedCirCleRadius > valueTwenty) {
                        mRedCirStrokeFactor = (int) (50 * changeValue);
                        mRedCirCleRadius = MAX_RADIUS_CIRCLE - mAroundLineInsideP;
                    }
                    //中心小黄球出现
                    mFirYellowCirRadius = (int) (10 * (1 - changeValue));
                }
                //底层黄球出现（环）
                if (factor > valueOnePointFive) {
                    changeValue = (factor - 1.5f) * 2;
                    mIsAroundPointV = true;
                    mAroundPointY = (int) ((MAX_RADIUS_CIRCLE / 2) * changeValue);
                    mSecYellowCirRadius = (int) (30 * changeValue);
                }
            }
        });
        secAnimator.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                thirdAnimator.start();
            }
        });
    }

    private void initFirstAnimation() {
        //黄色圆出现->黄色圆变成圆边矩形
        firAnimator = new AnimatorValue();
        firAnimator.setDuration(600);
        firAnimator.setLoopedCount(0);
        firAnimator.setValueUpdateListener((animatorValue, v) -> {
            float factor = 2 * v;
            if (factor < 1) {
                mFirYellowCirRadius = 20 + (int) ((float) factor * (MAX_RADIUS_CIRCLE - 20));
                mRedCirStrokeFactor = (int) (14 + (float) factor * 20);
            } else {
                mLineLeftOffset = (int) (MOVE_MAX_LINTH * (factor - 1));
            }
        });
        firAnimator.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                mFirYellowCirRadius = 0;
                mRedCirCleRadius = 60;
                mRedCirStrokeFactor = 50;
                mSecYellowCirRadius = 0;
                secAnimator.start();
            }

            @Override
            public void onStart(Animator animator) {
                super.onStart(animator);
                mIsCirLineShow = true;
            }
        });
    }


    @Override
    protected void initEndAnim() {
        //ValueAnimator.ofFloat(0, 1, 2)
        mEndAnimator = new AnimatorValue();
        mEndAnimator.setDuration(mDuration);
        mEndAnimator.setValueUpdateListener((ani, v) -> {
            float zoroToOne = (float) 2 * v;
            if (zoroToOne <= value_1) {
                mCurX = (int) (mPerX + zoroToOne * mEndMovingLength);
                mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                if (zoroToOne <= valueZeroPointFive) {
                    zoroToOne = 2 * zoroToOne;
                } else {
                    zoroToOne = 1 - 2 * (zoroToOne - 0.5f);
                }
                mEndCirMRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
            } else {
                if (!isMoveEnd) {
                    isMoveEnd = true;
                    if (mAnimatorStateListen != null) {
                        mAnimatorStateListen.onMoveEnd();
                    }
                }
                zoroToOne = 2 - zoroToOne;
                mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                if (zoroToOne >= valueZeroPointFive) {
                    zoroToOne = (1.0f - zoroToOne) * 2;
                } else {
                    zoroToOne = zoroToOne * 2;
                }
                mEndCirORadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
            }
        });
    }


    private void initPaint() {

        mEndMovingLength = -25;

        mPaint = new Paint();
        mPaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
        mPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        mPaint.setAntiAlias(true);
    }

    @Override
    public void startAnim() {
        super.startAnim();
        firAnimator.start();
    }

}
